package tbs.framework.async.container;

import org.jetbrains.annotations.NotNull;
import tbs.framework.async.container.model.AsyncTaskDetail;
import tbs.framework.utils.TryCatchUtils;

/**
 * 异步任务代理接口，用于管理异步任务的执行流程。
 */
public interface IAsyncTaskBroker {

    /**
     * 任务状态枚举。
     */
    public static enum TaskState {
        Before, Running, Finish
    }

    /**
     * 执行异步任务。
     *
     * @param task   异步任务详情
     * @param service 异步任务服务
     */
    default void execute(@NotNull AsyncTaskDetail task, @NotNull IAsyncTaskService service) {
        if (executeable(task, service)) {
            // 在任务执行前进行必要的准备工作
            TryCatchUtils.tryCatch(() -> {
                beforeExecute(task, service);
            }, (e) -> {
                // 处理任务准备阶段的失败情况
                onTaskFail(task, service, e, TaskState.Before);
            }, null);

            // 执行异步任务
            TryCatchUtils.tryCatch(() -> {
                task.getTask().execute(service);
            }, (e) -> {
                // 处理任务执行阶段的失败情况
                onTaskFail(task, service, e, TaskState.Running);
            }, null);

            // 在任务执行后进行收尾工作
            TryCatchUtils.tryCatch(() -> {
                afterExecute(task, service);
            }, (e) -> {
                // 处理任务完成阶段的失败情况
                onTaskFail(task, service, e, TaskState.Finish);
            }, null);
        }
    }

    /**
     * 检查任务是否可执行。
     *
     * @param task   异步任务详情
     * @param service 异步任务服务
     * @return 是否可执行
     */
    default boolean executeable(@NotNull AsyncTaskDetail task, @NotNull IAsyncTaskService service) {
        return !task.getTask().isRunning();
    }

    /**
     * 任务完成后调用的方法。
     *
     * @param task   异步任务详情
     * @param service 异步任务服务
     */
    void onTaskFinish(@NotNull AsyncTaskDetail task, @NotNull IAsyncTaskService service);

    /**
     * 在任务执行前调用的方法。
     *
     * @param task   异步任务详情
     * @param service 异步任务服务
     */
    void beforeExecute(@NotNull AsyncTaskDetail task, @NotNull IAsyncTaskService service);

    /**
     * 在任务执行后调用的方法。
     *
     * @param task   异步任务详情
     * @param service 异步任务服务
     */
    void afterExecute(@NotNull AsyncTaskDetail task, @NotNull IAsyncTaskService service);

    /**
     * 任务失败时调用的方法。
     *
     * @param task   异步任务详情
     * @param service 异步任务服务
     * @param e      异常
     * @param state  任务状态
     */
    void onTaskFail(@NotNull AsyncTaskDetail task, @NotNull IAsyncTaskService service, @NotNull Throwable e,
                    TaskState state);
}
